/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author xxxcsg
 * @brief sim_message工具，获取4g模块信息
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "cJSON.h"
#include "eagle_eys_server.h"
#include "common.h"

#define PORT 6543
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024

#ifndef EXIT_FAILURE
#define EXIT_FAILURE 0
#endif

void printfNullJson(void)
{
    cJSON *root = NULL;
    cJSON *baseinfo = NULL;
    cJSON *interfaceTraffic = NULL;
    cJSON *servingCell = NULL;

    char *jsonString = NULL;

    root = cJSON_CreateObject();
    if(!root)
    {
        printf("\033[31mjson root create error!\033[39m\n");
        return;
    }

    if(!cJSON_AddBoolToObject(root, "support4G", false))
    {
        printf("\033[31mjson support4G create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    baseinfo = cJSON_CreateObject();
    if(!baseinfo)
    {
        printf("\033[31mjson baseinfo create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    if(!cJSON_AddStringToObject(baseinfo,"manufacture", "NULL"))
    {
        printf("\033[31mjson manufacture create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"model", "NULL"))
    {
        printf("\033[31mjson model create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"imsi", "NULL"))
    {
        printf("\033[31mjson imsi create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"simId", "NULL"))
    {
        printf("\033[31mjson simId create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"ip", "NULL"))
    {
        printf("\033[31mjson ip create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddNumberToObject(baseinfo,"bandWidth", 0))
    {
        printf("\033[31mjson bandWidth create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"netType", "NULL"))
    {
        printf("\033[31mjson netType create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"devName", "NULL"))
    {
        printf("\033[31mjson devName create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"simStatus", "NULL"))
    {
        printf("\033[31mjson simStatus create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"modelFirmwareVersion", "NULL"))
    {
        printf("\033[31mjson modelFirmwareVersion create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"iccid", "NULL"))
    {
        printf("\033[31mjson iccid create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"imei", "NULL"))
    {
        printf("\033[31mjson imei create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"carrierInformation", "NULL"))
    {
        printf("\033[31mjson carrierInformation create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddItemToObject(root,"baseinfo",baseinfo))
    {
        goto exit;
        printf("baseinfo AddItem fail\n");
    }


    interfaceTraffic = cJSON_CreateObject();
    if(!interfaceTraffic)
    {
        printf("\033[31mjson interfaceTraffic create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"rxBytes", 0))
    {
        printf("\033[31mjson rxBytes create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"txBytes", 0))
    {
        printf("\033[31mjson txBytes create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"rxPackets", 0))
    {
        printf("\033[31mjson rxPackets create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"txPackets", 0))
    {
        printf("\033[31mjson txPackets create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddStringToObject(interfaceTraffic,"iface", "NULL"))
    {
        printf("\033[31mjson iface create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddItemToObject(root,"interfaceTraffic",interfaceTraffic))
    {
        goto exit1;
        printf("interfaceTraffic AddItem fail\n");
    }

    servingCell = cJSON_CreateObject();
    if(!servingCell)
    {
        printf("\033[31mjson servingCell create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }
    if(!cJSON_AddStringToObject(servingCell,"rsrp", "NULL"))
    {
        printf("\033[31mjson rsrp create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"rsrq", "NULL"))
    {
        printf("\033[31mjson rsrq create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"rssi", "NULL"))
    {
        printf("\033[31mjson rssi create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"sinr", "NULL"))
    {
        printf("\033[31mjson sinr create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"upSpeed", "NULL"))
    {
        printf("\033[31mjson upSpeed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"downSpeed", "NULL"))
    {
        printf("\033[31mjson downSpeed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"speed", "NULL"))
    {
        printf("\033[31mjson speed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddItemToObject(root,"servingCell",servingCell))
    {
        goto exit1;
        printf("servingCell AddItem fail\n");
    }

    jsonString = cJSON_Print(root);
    if(!jsonString)
    {
        printf("\033[31mjson jsonString create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    printf("%s\n", jsonString);
    free(jsonString);
    cJSON_Delete(root);
    return;

exit:
    cJSON_Delete(root);
    cJSON_Delete(baseinfo);
    return;

exit1:
    cJSON_Delete(root);
    cJSON_Delete(interfaceTraffic);
    return;

exit2:
    cJSON_Delete(root);
    cJSON_Delete(servingCell);
    return;
}

void printfMesgJson(ModuleMesg *mesg)
{
    cJSON *root = NULL;
    cJSON *baseinfo = NULL;
    cJSON *interfaceTraffic = NULL;
    cJSON *servingCell = NULL;

    char *jsonString = NULL;

    root = cJSON_CreateObject();
    if(!root)
    {
        printf("\033[31mjson root create error!\033[39m\n");
        return;
    }

    if(!cJSON_AddBoolToObject(root, "support4G", mesg->support4G))
    {
        printf("\033[31mjson support4G create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    baseinfo = cJSON_CreateObject();
    if(!baseinfo)
    {
        printf("\033[31mjson baseinfo create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    if(!cJSON_AddStringToObject(baseinfo,"manufacture", mesg->baseInfo.manufacture))
    {
        printf("\033[31mjson manufacture create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"model", mesg->baseInfo.model))
    {
        printf("\033[31mjson model create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"imsi", mesg->baseInfo.imsi))
    {
        printf("\033[31mjson imsi create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"simId", mesg->baseInfo.simId))
    {
        printf("\033[31mjson simId create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"ip", mesg->baseInfo.ip))
    {
        printf("\033[31mjson ip create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddNumberToObject(baseinfo,"bandWidth", mesg->baseInfo.bandWidth))
    {
        printf("\033[31mjson bandWidth create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"netType", mesg->baseInfo.netType))
    {
        printf("\033[31mjson netType create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"devName", mesg->baseInfo.devName))
    {
        printf("\033[31mjson devName create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"simStatus", mesg->baseInfo.simStatus))
    {
        printf("\033[31mjson simStatus create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"modelFirmwareVersion", mesg->baseInfo.modelFirmwareVersion))
    {
        printf("\033[31mjson modelFirmwareVersion create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"iccid", mesg->baseInfo.iccid))
    {
        printf("\033[31mjson iccid create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"imei", mesg->baseInfo.imei))
    {
        printf("\033[31mjson imei create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddStringToObject(baseinfo,"carrierInformation", mesg->baseInfo.carrierInformation))
    {
        printf("\033[31mjson carrierInformation create error!\033[39m\n");
        goto exit;
    }
    if(!cJSON_AddItemToObject(root,"baseinfo",baseinfo))
    {
        goto exit;
        printf("baseinfo AddItem fail\n");
    }


    interfaceTraffic = cJSON_CreateObject();
    if(!interfaceTraffic)
    {
        printf("\033[31mjson interfaceTraffic create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"rxBytes", mesg->interfaceTraffic.rxBytes))
    {
        printf("\033[31mjson rxBytes create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"txBytes", mesg->interfaceTraffic.txBytes))
    {
        printf("\033[31mjson txBytes create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"rxPackets", mesg->interfaceTraffic.rxPackets))
    {
        printf("\033[31mjson rxPackets create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddNumberToObject(interfaceTraffic,"txPackets", mesg->interfaceTraffic.txPackets))
    {
        printf("\033[31mjson txPackets create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddStringToObject(interfaceTraffic,"iface", mesg->interfaceTraffic.iface))
    {
        printf("\033[31mjson iface create error!\033[39m\n");
        goto exit1;
    }
    if(!cJSON_AddItemToObject(root,"interfaceTraffic",interfaceTraffic))
    {
        goto exit1;
        printf("interfaceTraffic AddItem fail\n");
    }

    servingCell = cJSON_CreateObject();
    if(!servingCell)
    {
        printf("\033[31mjson servingCell create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }
    if(!cJSON_AddStringToObject(servingCell,"rsrp", mesg->servingCell.rsrp))
    {
        printf("\033[31mjson rsrp create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"rsrq", mesg->servingCell.rsrq))
    {
        printf("\033[31mjson rsrq create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"rssi", mesg->servingCell.rssi))
    {
        printf("\033[31mjson rssi create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"sinr", mesg->servingCell.sinr))
    {
        printf("\033[31mjson sinr create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"upSpeed", mesg->servingCell.upSpeed))
    {
        printf("\033[31mjson upSpeed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"downSpeed", mesg->servingCell.downSpeed))
    {
        printf("\033[31mjson downSpeed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddStringToObject(servingCell,"speed", mesg->servingCell.speed))
    {
        printf("\033[31mjson speed create error!\033[39m\n");
        goto exit2;
    }
    if(!cJSON_AddItemToObject(root,"servingCell",servingCell))
    {
        goto exit1;
        printf("servingCell AddItem fail\n");
    }

    jsonString = cJSON_Print(root);
    if(!jsonString)
    {
        printf("\033[31mjson jsonString create error!\033[39m\n");
        cJSON_Delete(root);
        return;
    }

    printf("%s\n", jsonString);
    free(jsonString);
    cJSON_Delete(root);
    return;

exit:
    cJSON_Delete(root);
    cJSON_Delete(baseinfo);
    return;

exit1:
    cJSON_Delete(root);
    cJSON_Delete(interfaceTraffic);
    return;

exit2:
    cJSON_Delete(root);
    cJSON_Delete(servingCell);
    return;
}

int CJSON_CDECL main( int argc, char *argv[] ) 
{
    if(argc == 2)
    {
        if(!strcmp(argv[1],"-v"))
        {
            printf_func_version(HAWK_EYE_FUNC_SIM_MESG);
        }
        return 0;
    }
    
    int sock = 0, valread = 0;
    struct sockaddr_in serv_addr;
    char buffer[BUFFER_SIZE] = {0};
    // char *message = "Hello from client";
    EagleEysBusiness package = {0};

    // 创建socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        // perror("socket creation failed");
        printfNullJson();
        exit(EXIT_FAILURE);
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // 将IPv4地址换
    if(inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr)<=0) {
        // perror("Invalid address/ Address not supported");
        printfNullJson();
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        // perror("Connection Failed");
        printfNullJson();
        exit(EXIT_FAILURE);
    }

    package.type = GET_4G_MODULE_INFO;
    // 发送消息给服务器
    send(sock, (char*)&package, sizeof(package), 0);
    // printf("Client: Message sent to server\n");

    // 接收服务器响应
    valread = read(sock, buffer, BUFFER_SIZE);
    // printf("read len:%d\n", valread);

    if(valread)
    {
        EagleEysBusinessPackage *tmp = (EagleEysBusinessPackage*)buffer;
        // printf("type:%d,len:%d\n", tmp->type, tmp->len);
        if(tmp->type == GET_4G_MODULE_INFO && tmp->len)
        {
            ModuleMesg* mesg = (ModuleMesg*)tmp->data;
            printfMesgJson(mesg);
        }
        else
        {
            printfNullJson();
        }
    }
    else
    {
        // printf("recv error\n");
        printfNullJson();
    }

    close(sock);

    return 0;

}
